From b5a0388318fa6d23425f64ae0f0779d96dce7295 Mon Sep 17 00:00:00 2001 From: "mafetter@fleming.research" Date: Sat, 12 Feb 2005 13:42:57 +0000 Subject: [PATCH] bitkeeper revision 1.1159.260.1 (420e07e16YlSevQI9RYNGLwarPr2gQ) Bug fix for shadow code. When update_va_mapping() updates a entry, the corresponding shadow entry may not be reachable via the shadow_linear_pg_table, even though it is currently shadowed, as the corresponding spde has not necessarily been faulted into place yet. --- xen/arch/x86/memory.c | 22 +++++++++++++++++++--- xen/include/xen/perfc_defn.h | 3 ++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 631e5c50c9..3961b37a89 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -1573,10 +1573,26 @@ int do_update_va_mapping(unsigned long page_nr, &shadow_linear_pg_table[page_nr])))) ) { /* - * Since L2's are guranteed RW, failure indicates the page was not - * shadowed, so ignore. + * Since L2's are guranteed RW, failure indicates either that the + * page was not shadowed, or that the L2 entry has not yet been + * updated to reflect the shadow. */ - perfc_incrc(shadow_update_va_fail); + unsigned l2_idx = page_nr >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT); + l2_pgentry_t gpde = linear_l2_table[l2_idx]; + unsigned long gpfn = l2_pgentry_val(gpde) >> PAGE_SHIFT; + + if (get_shadow_status(&d->mm, gpfn)) + { + unsigned long *gl1e = map_domain_mem(gpfn << PAGE_SHIFT); + unsigned l1_idx = page_nr & (ENTRIES_PER_L1_PAGETABLE - 1); + gl1e[l1_idx] = sval; + unmap_domain_mem(gl1e); + put_shadow_status(&d->mm); + + perfc_incrc(shadow_update_va_fail1); + } + else + perfc_incrc(shadow_update_va_fail2); } /* diff --git a/xen/include/xen/perfc_defn.h b/xen/include/xen/perfc_defn.h index f6868d78b9..d5dc9436ff 100644 --- a/xen/include/xen/perfc_defn.h +++ b/xen/include/xen/perfc_defn.h @@ -25,7 +25,8 @@ PERFCOUNTER_CPU( shadow_l2_table_count, "shadow_l2_table count" ) PERFCOUNTER_CPU( shadow_l1_table_count, "shadow_l1_table count" ) PERFCOUNTER_CPU( unshadow_table_count, "unshadow_table count" ) PERFCOUNTER_CPU( shadow_fixup_count, "shadow_fixup count" ) -PERFCOUNTER_CPU( shadow_update_va_fail, "shadow_update_va_fail" ) +PERFCOUNTER_CPU( shadow_update_va_fail1, "shadow_update_va_fail1" ) +PERFCOUNTER_CPU( shadow_update_va_fail2, "shadow_update_va_fail2" ) /* STATUS counters do not reset when 'P' is hit */ PERFSTATUS( shadow_l2_pages, "current # shadow L2 pages" ) -- 2.30.2